import 'package:flutter/material.dart';
import 'package:flutter_demo1/db/hi_cache.dart';
import 'package:flutter_demo1/http/dao/login_dao.dart';
import 'package:flutter_demo1/model/video_model.dart';
import 'package:flutter_demo1/navigator/bottom_navigator.dart';
import 'package:flutter_demo1/navigator/hi_navigator.dart';
import 'package:flutter_demo1/page/login_page.dart';
import 'package:flutter_demo1/page/registration_page.dart';
import 'package:flutter_demo1/page/video_detail_page.dart';
import 'package:flutter_demo1/util/color.dart';
import 'package:flutter_demo1/util/toast.dart';

void main() {
  runApp(const BiliApp());
}

class BiliApp extends StatefulWidget {
  const BiliApp({super.key});

  @override
  State<BiliApp> createState() => _BiliAppState();
}

class _BiliAppState extends State<BiliApp> {
  final BiliRouteDelegate _biliRouteDelegate = BiliRouteDelegate();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: HiCache.preInit(),
      builder: (BuildContext context, AsyncSnapshot<HiCache> snapshot) {
        var widget = snapshot.connectionState == ConnectionState.done
            ? Router(routerDelegate: _biliRouteDelegate)
            : Scaffold(body: Center(child: CircularProgressIndicator()));
        return MaterialApp(
          theme: ThemeData(primarySwatch: white),
          home: widget,
        );
      },
    );
  }
}

class BiliRouteDelegate extends RouterDelegate<BiliRoutePath>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<BiliRoutePath> {
  @override
  final GlobalKey<NavigatorState> navigatorKey;

  //为navigator设置一个key,必要时可以通过navigationKey.currentState来获取到NavigatorState对象
  BiliRouteDelegate() : navigatorKey = GlobalKey<NavigatorState>() {
    //在main的这个位置，为HiNavigator注册了一个能够路由导航的能力
    HiNavigator.getInstance().registerRouteJump(
      RouteJumpListener(
        onJumpTo: (RouteStatus routeStatus, {Map<String, dynamic>? args}) {
          _routeStatus = routeStatus;
          if (_routeStatus == RouteStatus.detail) {
            videoModel = args?["videoModel"];
          }
          notifyListeners();
        },
      ),
    );
  }

  RouteStatus _routeStatus = RouteStatus.home;
  List<MaterialPage> pages = [];
  VideoModel? videoModel;
  BiliRoutePath? path;

  @override
  Widget build(BuildContext context) {
    print("BiliRouteDelegate----build");
    var index = getPageIndex(pages, routeStatus);
    List<MaterialPage> tempPages = pages;
    if (index != -1) {
      ///要打开的页面已经在页面栈中存在,将该页面和上他面的页面进行出栈
      ///tips 具体规则可以根据需要进行调整,这里要求栈中只允许同样的页面只能有一个实例
      tempPages = tempPages.sublist(0, index);
    }
    var page;
    if (routeStatus == RouteStatus.home) {
      page = pageWrap(BottomNavigator());
    } else if (routeStatus == RouteStatus.detail) {
      page = pageWrap(VideoDetailPage(videoModel!));
    } else if (routeStatus == RouteStatus.registration) {
      page = pageWrap(RegistrationPage());
    } else if (routeStatus == RouteStatus.login) {
      page = pageWrap(LoginPage());
    }
    tempPages = [...tempPages, page];

    //新旧页面转换时执行导航器监听
    HiNavigator.getInstance().notify(tempPages, pages);

    //把新的页面栈集合复制给要创建的栈集合
    pages = tempPages;

    return WillPopScope(
      onWillPop: () async => !await navigatorKey.currentState!.maybePop(),
      child: Navigator(
        key: navigatorKey,
        pages: pages,
        onPopPage: (route, result) {
          if ((route.settings is MaterialPage)) {
            //登录页未登录返回拦截
            if ((route.settings as MaterialPage).child is LoginPage) {
              if (!hasLogin) {
                showWarnToast("清先登录");
                return false;
              }
            }
          }
          if (!route.didPop(result)) {
            return false;
          }
          var tempPages = [...pages];
          pages.removeLast();
          //新旧页面转换时执行导航器监听
          HiNavigator.getInstance().notify(pages, tempPages);
          return true;
        },
      ),
    );
  }

  RouteStatus get routeStatus {
    if (_routeStatus != RouteStatus.registration && !hasLogin) {
      return _routeStatus = RouteStatus.login;
    } else if (videoModel != null) {
      return _routeStatus = RouteStatus.detail;
    } else {
      return _routeStatus;
    }
  }

  bool get hasLogin => LoginDao.getBoardingPass() != null;

  @override
  Future<void> setNewRoutePath(BiliRoutePath path) async {
    this.path = path;
  }
}

//定义路由数据
class BiliRoutePath {
  final String location;

  BiliRoutePath.home() : location = "/";

  BiliRoutePath.detail() : location = "/detail";
}

pageWrap(Widget child) {
  return MaterialPage(key: ValueKey(child.hashCode), child: child);
}
